#pragma once
#include <iostream>
#include <sys/types.h>
#include <vector>
#include <sys/wait.h>
#include "Channel.hpp"
#include "Task.hpp"

class ProcessPool
{
public:
    ProcessPool(int processnum) : _processnum(processnum)
    {
    }

    int CreateProcess(work_t work)
    {
        for (int num = 0; num < _processnum; num++)
        {
            int pipefd[2]{0};
            int n = pipe(pipefd);
            if(n < 0) return 2;
            pid_t id = fork();
            if(id == 0)
            {
                // 子进程读
                close(pipefd[1]);
                dup2(pipefd[0], 0);//重定向到管道
                // 任务
                work(pipefd[0]);
                exit(1);//终止！！！
            }
            // 父进程写
            close(pipefd[0]);
            string cname = "thread-" + to_string(num);
            _channels.push_back(Channel(pipefd[1], id, cname));
        }
        return 1;
    }

    void Send(int index, uint32_t code)
    {
        cout << "send fd: " << index << " to" << _channels[index].Name() 
        << " subprocessid: " <<  _channels[index].Id() << endl;
        write(_channels[index].Wfd(), &code, sizeof(code));
    }

    int NextChannel()
    {
        static int next = 0;
        int c = next;
        next++;
        next %= _channels.size();
        return c;
    }

    void KillAll()
    {
        for(auto channel:_channels)
        {
            channel.Close();
            cout << channel.Name() << "close done, sub process: " << channel.Id() << endl; 
        }
    }

    void Wait()
    {
        for(auto channel:_channels)
        {
            pid_t pid = channel.Id();
            int rid = waitpid(pid, nullptr, 0);
            if(rid == pid)
            {
                cout << "sub process: "<<pid << " wait success" << endl;
            }
        }
    }

    ~ProcessPool()
    {
    }

private:
    int _processnum;
    vector<Channel> _channels;
};